package cn.com.bluemoon.daps.sync.core.sync.compare.devmodel;

import cn.com.bluemoon.daps.api.model.RemoteDataModelTableIndexService;
import cn.com.bluemoon.daps.common.domain.ResultBean;
import cn.com.bluemoon.daps.common.toolkit.BmAssetUtils;
import cn.com.bluemoon.daps.model.entity.DapDataModelSubordinateKey;
import cn.com.bluemoon.daps.model.entity.DapDataModelTable;
import cn.com.bluemoon.daps.model.entity.DapDataModelTableField;
import cn.com.bluemoon.daps.sync.base.DevModelCompareResult;
import cn.com.bluemoon.daps.sync.core.sync.GlobalConfig;
import cn.com.bluemoon.daps.sync.core.sync.Tuple2;
import cn.com.bluemoon.daps.sync.core.sync.compare.IndexComparator;
import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Jarod.Kong
 * @date 2021/6/3 13:43
 */
@Slf4j
public class Dev2ModelIndexComparator extends IndexComparator<DevModelCompareResult> {
    private final RemoteDataModelTableIndexService indexService;

    public Dev2ModelIndexComparator(GlobalConfig globalConfig, Tuple2<DapDataModelTable> tableTuple2) {
        super(globalConfig, tableTuple2);
        indexService = SpringUtil.getBean(RemoteDataModelTableIndexService.class);
        if (globalConfig.isAddSink()) {
            BmAssetUtils.notNull(indexService, "入库DB，服务类不可为空");
        }
    }

    @Override
    public void change0(List<DevModelCompareResult> collector) {
        super.change0(collector);
        collector.add(DevModelCompareResult.builder()
                .type(DevModelCompareResult.Type.Index)
                .action(DevModelCompareResult.Action.Update)
                .devProp(getNewT().getKeyName())
                .modelProp(getOldT().getKeyName())
                .build());
        if (globalConfig.isAddSink()) {
            getNewT().setFieldIds(getFieldIds());
            ResultBean<Boolean> res = indexService.updateById(getOldT().getId(), getNewT());
            BmAssetUtils.isTrue(res.isOk(), res.getMsg());
            Boolean status = res.getContent();
            log.info("更新表表索引，{}, 情况：{}", getTableId(), status);
        }
    }

    public String getFieldIds() {
        // 获取所有
        List<DapDataModelTableField> tableFieldsAndIds = getV1AndV2DbFields().stream().flatMap(t -> {
            DapDataModelTableField oldT = t.getOldT();
            DapDataModelTableField newT = t.getNewT();
            return Stream.of(oldT, newT).filter(Objects::nonNull);
        }).collect(Collectors.toList());
        Map<String, DapDataModelTableField> fieldNameAndField = tableFieldsAndIds.stream().filter(d -> d.getId() != null).collect(Collectors.toMap(DapDataModelTableField::getFieldName, d -> d, (a, b) -> b));
        String fieldIds = Arrays.stream(getNewT().getFieldNamesSplit()).filter(fieldNameAndField::containsKey).map(f -> fieldNameAndField.get(f).getId()).collect(Collectors.joining(DapDataModelSubordinateKey.INDEX_FIELDIDS_CHAR));
        return fieldIds;
    }

    @Override
    public void drop0(List<DevModelCompareResult> collector) {
        DevModelCompareResult.Action action = DevModelCompareResult.Action.Delete;
        if (!globalConfig.isCanDropDbTable() && oldTable != null && newTable == null){
            action = DevModelCompareResult.Action.Ignore;
            log.debug("Dev2ModelIndexComparator#drop0，表级别中，库表无，模型有，忽略，不进行入库");
        }
        super.drop0(collector);
        collector.add(DevModelCompareResult.builder()
                .type(DevModelCompareResult.Type.Index)
                .action(action)
                .devProp("")
                .modelProp(getOldT().getKeyName())
                .build());
        // 2021/6/16 开发库同步到模型 逻辑调整：开发库表中无，模型中有的表级别，不对模型中的表删除，字段级别对比则进行删除
        if (globalConfig.isAddSink() && !DevModelCompareResult.Action.Ignore.equals(action)) {
            boolean status = indexService.removeById(getOldT().getId()).getContent();
            log.info("删除表索引，{}, 情况：{}", getTableId(), status);
        }
    }

    @Override
    public void create0(List<DevModelCompareResult> collector) {
        super.create0(collector);
        collector.add(DevModelCompareResult.builder()
                .type(DevModelCompareResult.Type.Index)
                .action(DevModelCompareResult.Action.Create)
                .devProp(getNewT().getKeyName())
                .modelProp("").build());
        if (globalConfig.isAddSink()) {
            getNewT().setModelTableId(getTableId());
            getNewT().setDataModelId(globalConfig.getModel().getId());
            getNewT().setFieldIds(getFieldIds());
            ResultBean<String> res = indexService.saveIndex(getNewT());
            BmAssetUtils.isTrue(res.isOk(), res.getMsg());
            String indexId = res.getContent();
            getNewT().setId(indexId);
            log.info("增加表索引，{}, id：{}", getTableId(), indexId);
        }
    }
}
